/******************************************************************************
** 
**	File name: utest_30.c
**	
**	Description:	RTOS Ver.2 Unit Tests. Event Management from ISR.
**
**					This unit test is to check the event capabilities
**					when setting it from interrupts. 
**
**  RTOS API Services to be checked:
**
**		- RTOS_SetEventISR()
**		- RTOS_WaitEvent()
**
**  Notes:			This is MANUAL test!
**
******************************************************************************/
#include <avr/io.h>
#include <avr/interrupt.h>
#include "rtos.h"
#include "utest.h"

/******************************************************************************
**	RTOS DECLARARTION SECTION
**
**  Standard config for RTOS MESSAGE QUEUE Services Unit Tests should look
**	as follows:
**
**	Timer interrupt #1:			SYSTEM_TimerHandler (defined by USER)
**	Timer interrupt #2:			// not used USER_TimerHandler_1 (defined by USER)
**	Timer interrupt #3:			// not used USER_TimerHandler_2 (defined by USER)
**
**	Timers:						n/a
**	Events:									evt1,		evt2,		evt3
**	Messages:								msg1		msg2		msg3
**	Queues:									msq1		msq2		msq3
**	Timers:						n/a
**	
**	Three tasks:				tsk0,		tsk1,		tsk2,		tsk3 
**  Three priorities:			0(highest)	1 (high)	2 (middle)	3 (low)
**  Stack size:					8			20			20			20
**
**  Notes:						tsk0 is only for stack overflow control!!!
**
******************************************************************************/

RTOS_DECLARE_ISR(SYSTEM_TIMER_VECTOR,SYSTEM_TimerHandler);
RTOS_DECLARE_ISR(USER_TIMER_1_VECTOR,USER_TimerHandler_1);
RTOS_DECLARE_ISR(USER_TIMER_2_VECTOR,USER_TimerHandler_2);

RTOS_DECLARE_TASK(tsk0,  8, 0);
RTOS_DECLARE_TASK(tsk1, 20, 1);
RTOS_DECLARE_TASK(tsk2, 20, 2);
RTOS_DECLARE_TASK(tsk3, 20, 3);

RTOS_DECLARE_EVENT(evt1);
RTOS_DECLARE_EVENT(evt2);
RTOS_DECLARE_EVENT(evt3);

RTOS_DECLARE_MESSAGE(msg1);
RTOS_DECLARE_MESSAGE(msg2);
RTOS_DECLARE_MESSAGE(msg3);

RTOS_DECLARE_MESSAGEQ(msq1);
RTOS_DECLARE_MESSAGEQ(msq2);
RTOS_DECLARE_MESSAGEQ(msq3);

extern void UTST_FillRegisters( void );

UTST_TIMER_t	sys_tmr = 
{
	&(SYSTEM_TIMER),
	500,
	LEVEL_HIGH,
	STATE_STOP
};

UTST_TIMER_t	usr_tmr_1 =
{
	&(USER_TIMER_1),
	10001,
	LEVEL_MED,
	STATE_STOP
};

UTST_TIMER_t	usr_tmr_2 =
{
	&(USER_TIMER_2),
	20000,
	LEVEL_LOW,
	STATE_STOP
};



/******************************************************************************
	UNIT TEST MAIN FUNCTION
******************************************************************************/
void main(void)
{
	UTST_INIT_HW();

//	utst_init_timer(&sys_tmr);
	utst_init_timer(&usr_tmr_1);
//	utst_init_timer(&usr_tmr_2);
	
    RTOS_TaskInitExp (tsk0);	// Init but not start ))
    RTOS_TaskStartExp(tsk1);
    RTOS_TaskStartExp(tsk2);
    RTOS_TaskStartExp(tsk3);
	
//	UTST_TIMER_START(SYSTEM_TIMER);
	UTST_TIMER_START(USER_TIMER_1);
//	UTST_TIMER_START(USER_TIMER_2);

    RTOS_Initialize(0);
	RTOS_StartOS();
	
    while(1);	
}


/******************************************************************************
	UNIT TEST INTERRUPT FUNCTION[s]
******************************************************************************/
/*
** Dummy Timer Handler
*/
RTOS_ISR_FUNC(SYSTEM_TimerHandler)
{
	RTOS_HaltOS();
}

/*
** User' Timer 1 ISR Handler
*/
RTOS_ISR_FUNC(USER_TimerHandler_1)
{
	RTOS_DebugPrint("Timer #1 ISR: Set all events.");
	RTOS_SetEventISR(&evt1);
	RTOS_SetEventISR(&evt2);
	RTOS_SetEventISR(&evt3);
}

/*
** User' Timer 1 ISR Handler
*/
RTOS_ISR_FUNC(USER_TimerHandler_2)
{
	RTOS_HaltOS();
}
	
/******************************************************************************
	UNIT TEST TASK FUNCTIONs
******************************************************************************/
/*
** RTOS Task #0 - Stack checking task
*/
RTOS_TASK_FUNC(tsk0)
{
	while (1)
	{
		RTOS_DebugPrint("Checking stack consistency...");
		RTOS_StackCheck(tsk0);
		RTOS_StackCheck(tsk1);
		RTOS_StackCheck(tsk2);
		RTOS_StackCheck(tsk3);
		RTOS_DebugPrint("All OK!");		
		RTOS_TaskSuspend(&tsk0PID);
	}
}

/*
** RTOS Task #1
*/
RTOS_TASK_FUNC(tsk1)
{
	UTST_FillRegisters();
	while(1)
	{
		RTOS_TaskResume(&tsk0PID);		// activate stack control check
		RTOS_DebugPrint("Task #1 blocks on wait...");
		RTOS_WaitEvent(&evt1);		
		RTOS_DebugPrint("Task #1 resumed.");		
	}
}

/*
** RTOS Task #2 
*/
RTOS_TASK_FUNC(tsk2)
{
	UTST_FillRegisters();
	while(1)
	{
		RTOS_TaskResume(&tsk0PID);		// activate stack control check
		RTOS_DebugPrint("Task #2 blocks on wait...");
		RTOS_WaitEvent(&evt2);		
		RTOS_DebugPrint("Task #2 resumed.");		
	}
}

/*
** RTOS Task #3 
*/
RTOS_TASK_FUNC(tsk3)
{
	UTST_FillRegisters();
	while(1)
	{
		RTOS_TaskResume(&tsk0PID);		// activate stack control check
		RTOS_DebugPrint("Task #3 blocks on wait...");
		RTOS_WaitEvent(&evt3);		
		RTOS_DebugPrint("Task #3 resumed.");		
	}
}
